/*
  Serial Event example

 When new serial data arrives, this sketch adds it to a String.
 When a newline is received, the loop prints the string and
 clears it.

 A good test for this is to try it with a GPS receiver
 that sends out NMEA 0183 sentences.

 Created 9 May 2011
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialEvent

 */
#include <MsTimer2.h>

#include <SoftwareSerial.h>

SoftwareSerial DSG3_Serial(10, 11); // RX, TX

String inputString = "";         // a string to hold incoming data
String serial_inputString="";
boolean stringComplete = false;  // whether the string is complete
String result_string= "     ";
unsigned int water_level = 6;
int LED = 13;
int VALVE = 2;
bool led_value = 0;
int time_count = 0;
int heart_pulse_count = 60;
int key_out = 8;
int key_in = 9;
int wait_dsg3_stable = 0;
int one_time_open_count = 0;
int time_out_count = 0;
void time_count_f()
{
    if(heart_pulse_count > 0) 
    heart_pulse_count--;
    else
    digitalWrite(VALVE, LOW); //heart pulse timeout close valve.
    
    if(one_time_open_count > 2)
    one_time_open_count--;
    else if(one_time_open_count == 2)
    {
      digitalWrite(VALVE, LOW);
       one_time_open_count--; 
    }
    
    if(wait_dsg3_stable < 30)
    wait_dsg3_stable++;
}

void setup() {
  char inChar;
  // initialize serial:
  pinMode(LED, OUTPUT);
  pinMode(VALVE, OUTPUT);
  pinMode(key_out, OUTPUT);
  pinMode(key_in, INPUT_PULLUP);
  digitalWrite(key_out, LOW);
  
  MsTimer2::set(1000, time_count_f); // 1000ms period
  MsTimer2::start();
  
  Serial.begin(9600);
  DSG3_Serial.begin(1200);
  // reserve 200 bytes for the inputString:
   inputString.reserve(100);
   serial_inputString.reserve(100);
   //DSG3_Serial.println("ver");
   time_count = 10;
   while(time_count--)
   {
     led_value = !led_value;
     digitalWrite(LED, led_value);
     delay(1000);
     Serial.println(time_count);
   }
   
   
   while (DSG3_Serial.available()) DSG3_Serial.read();
   inputString = "";
   DSG3_Serial.println("mode=0");
   Serial.println("mode=0");
   delay(1000);
  time_out_count = 50;
   while(time_out_count--)
   {
   while (DSG3_Serial.available()) {
    // get the new byte:
    inChar = (char)DSG3_Serial.read();
    inputString += inChar;
    if (inChar == '\n' && (inputString.length() > 3)) {
      Serial.print(inputString);
       time_out_count = 0;
      break;
    }
    
    }
   delay(100);
   }
  
   inputString = "";
   DSG3_Serial.println("algthm");
   Serial.println("algthm");
   delay(1000);
   time_out_count = 50;
   while(time_out_count--)
   {
   while (DSG3_Serial.available()) {
    // get the new byte:
    inChar = (char)DSG3_Serial.read();
    inputString += inChar;
    if (inChar == '\n' && (inputString.length() > 3)) {
      Serial.print(inputString);
      inputString = inputString.substring(3);
      if(inputString.indexOf("On")==(-1))
      {
        DSG3_Serial.println("algthm");
        Serial.print("indexof");Serial.println( inputString.indexOf("On"));
        Serial.println("send algthm again");
      }
      time_out_count = 0;
      break;
    }
   }
   delay(100);
  }
    inputString = "";
}

void LED_Blink(unsigned int value)
{
  while(value--)
  {
  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);              // wait for a second
  digitalWrite(LED, LOW);    // turn the LED off by making the voltage LOW
  delay(200);              // wait for a second
  }
}

void loop() {
  // print the string when a newline arrives:
  DSG3_Serial_Check();
  
  if(digitalRead(key_in) == LOW)
  {
     delay(100);
     if(digitalRead(key_in) == LOW)
    {
      digitalWrite(VALVE, HIGH);
      one_time_open_count = 10;
     }
  }
  
  if(wait_dsg3_stable < 60)
  return;
  
  if (stringComplete) {
    if(inputString.startsWith("TmpCoC")!=true){
      
      inputString = "";
      stringComplete = false;
      return;
    }
    heart_pulse_count = 30; //heart pulse set to 30 second.
    result_string = inputString.substring(inputString.lastIndexOf(', '));
    water_level = result_string.toInt();
    if(water_level >= 6)
    water_level = 6;
    
    if(water_level >= 5)
    {
      digitalWrite(VALVE, LOW);
      digitalWrite(LED, LOW);
    }
    
    if(water_level <= 1)
    {
      digitalWrite(VALVE, HIGH);
      digitalWrite(LED, HIGH);
    }
    
    result_string = "";
    //LED_Blink(water_level+1);
    Serial.print("water level:");
    Serial.println(water_level);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void DSG3_Serial_Check() {
  while (DSG3_Serial.available()) {
    // get the new byte:
    char inChar = (char)DSG3_Serial.read();
    // add it to the inputString:    
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
      Serial.print("r:"+inputString);
      return ;
    }
    
  }
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:    
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    serial_inputString += inChar;
    if (inChar == '\n') {
      DSG3_Serial.print(serial_inputString);
      Serial.print("w:"+serial_inputString);
      serial_inputString = "";
      return ;
    }
    
  }
}



